/**
 * 
 */
package com.googlecode.cswish.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ClassUtils;
import org.apache.log4j.Logger;

import com.googlecode.cswish.struts.hibernate.DynamicModel;


/**
 * It stores all the persistence properties and top interface properties
 * 
 * @author Jerry.Feng Date: 2008-4-10
 */
public class ModelInfo {

	private static final Logger logger = Logger.getLogger(ModelInfo.class);
	
	/**
	 * table name
	 */
	private String table;
	
	/**
	 * class type
	 */
	private String type;
	
	private String genericType;
	
	private String simpleName;

	/**
	 * it store all the model property
	 * property name , property info
	 */
	private Map<String, PropertyInfo> properties;
	private List<PropertyInfo> persistencePropertiesCache;
	private List<PropertyInfo> interfacePropertiesCache;
	
	/**
	 * the dynamic class name to store persistence property
	 * property name, container name -- section/layout etc
	 */
	private Map<String, String> propertyContainer;
	
	private List<String> references;

	public ModelInfo() {
		properties = new HashMap<String, PropertyInfo>();
		propertyContainer = new HashMap<String, String>();
		persistencePropertiesCache = new ArrayList<PropertyInfo>();
		interfacePropertiesCache = new ArrayList<PropertyInfo>();
	}
	
	public String getTable() {
		return table;
	}
	
	public void setTable(String table) {
		this.table = table;
	}

	public String getSimpleName() {
		return simpleName;
	}
	
	public void setSimpleName(String simpleName) {
		this.simpleName = simpleName;
	}
	
	public PropertyInfo getProperty(String name) {
		return properties.get(name);
	}

	public PropertyInfo addProperty(String containerName, PropertyInfo propertyInfo,
			boolean isInterfaceProperty, boolean isPersistenceProperty) {
		PropertyInfo old = properties.put(propertyInfo.getName(), propertyInfo);
		if (containerName != null) {
			propertyContainer.put(propertyInfo.getName(), containerName);
		}
		if (isInterfaceProperty) {
			interfacePropertiesCache.add(propertyInfo);
		}
		if (isPersistenceProperty) {
			persistencePropertiesCache.add(propertyInfo);
		}
		return old;
	}
	
	public PropertyInfo removeProperty(Object propertyName) {
		PropertyInfo propertyInfo = properties.remove(propertyName);
		if (propertyInfo != null) {
			interfacePropertiesCache.remove(propertyInfo);
			persistencePropertiesCache.remove(propertyInfo);
		}
		return propertyInfo;
	}
	
	public List<PropertyInfo> getInterfaceProperties() {
		return interfacePropertiesCache;
	}
	
	public List<PropertyInfo> getPersistenceProperties() {
		return persistencePropertiesCache;
	}
	
	public Collection<PropertyInfo> getAllProperties() {
		return properties.values();
	}
	
	public String getContainerName(String propertyName) {
		return propertyContainer.get(propertyName);
	}

	public String getType() {
		return type;
	}
	
	public Class<?> getTypeClass() {
		try {
			return ClassUtils.getClass(type);
		} catch (ClassNotFoundException ex) {
			logger.debug("type is not valid class:" + type);
			return DynamicModel.class;
		}
	}

	public void setType(String type) {
		this.type = type;
		
		// Default generic type is same with type
		if (this.genericType == null) {
			this.genericType = type;
		}
	}
	
	public String toString() {
		return (this.type != null ? this.type : "") + '<' 
		+ (this.genericType != null ? this.genericType : "") + '>';
	}
	
	public String getGenericType() {
		return genericType;
	}

	public void setGenericType(String genericType) {
		this.genericType = genericType;
	}
}